home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-07-05 | 35.5 KB | 1,508 lines |
- head 2.1;
- branch ;
- access ;
- symbols before_fairness_changes:2.0 ckpt1:1.3;
- locks ; strict;
- comment @ * @;
-
-
- 2.1
- date 90.07.05.13.19.38; author douglis; state Exp;
- branches ;
- next 2.0;
-
- 2.0
- date 90.06.30.17.09.21; author douglis; state Stable;
- branches ;
- next 1.9;
-
- 1.9
- date 90.05.28.17.07.27; author douglis; state Exp;
- branches ;
- next 1.8;
-
- 1.8
- date 90.05.02.12.31.27; author douglis; state Exp;
- branches ;
- next 1.7;
-
- 1.7
- date 90.04.27.00.59.18; author douglis; state Exp;
- branches ;
- next 1.6;
-
- 1.6
- date 90.04.24.18.00.41; author douglis; state Exp;
- branches ;
- next 1.5;
-
- 1.5
- date 90.04.03.11.09.35; author douglis; state Exp;
- branches ;
- next 1.4;
-
- 1.4
- date 90.03.14.12.49.57; author douglis; state Exp;
- branches ;
- next 1.3;
-
- 1.3
- date 90.03.12.13.45.47; author douglis; state Exp;
- branches ;
- next 1.2;
-
- 1.2
- date 90.02.28.10.50.24; author douglis; state Exp;
- branches ;
- next 1.1;
-
- 1.1
- date 90.02.15.19.19.06; author douglis; state Exp;
- branches ;
- next ;
-
-
- desc
- @Routines to manage pseudo-devices for the migration daemon.
- This is also the only file that deals with byte ordering issues.
- @
-
-
- 2.1
- log
- @nothing major.
- @
- text
- @/*
- * migPdev.c --
- *
- * Routines to manage pseudo-devices for the migration daemon.
- * This is also the only file that deals with byte ordering issues.
- *
- * Most operations are done using ioctls. Reads and writes are used
- * for the following purpose:
- *
- * - the loadavg daemons write load vectors asynchronously,
- * - user processes can read load vectors for their own host
- * (synchronously), and
- * - user processes can select on the pdev to find out about changes
- * in the state of idle hosts (new ones available or ones being
- * reclaimed).
- *
- * Copyright 1989, 1990 Regents of the University of California
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: /sprite/src/daemons/migd/RCS/migPdev.c,v 2.0 90/06/30 17:09:21 douglis Stable Locker: douglis $ SPRITE (Berkeley)";
- #endif /* not lint */
-
- #include <sprite.h>
- #include <string.h>
- #include <errno.h>
- #include <status.h>
- #include "syslog.h"
- #include <bstring.h>
- #include <fs.h>
- #include <kernel/fs.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <sys/dir.h>
- #include <sys/stat.h>
- #include <host.h>
- #include <pdev.h>
- #include <fmt.h>
- #include "migd.h"
- #include "migPdev.h"
- #include "global.h"
-
-
- static int PdevOpen(), PdevClose(), PdevWrite();
- static int PdevRead(), PdevIoctl();
-
- static Pdev_CallBacks service = {
- PdevOpen, /* open */
- PdevRead, /* read */
- PdevWrite, /* write */
- PdevIoctl, /* ioctl */
- PdevClose, /* close */
- NULL, NULL /* get/set attr */
- };
-
- typedef struct {
- int (*routine)(); /* routine to call */
- char *inFmt; /* string to pass to Fmt_Convert for input */
- char *outFmt; /* string to pass to Fmt_Convert for output */
- } IoctlCallback;
-
-
- /*
- * Define fmt conversions for the structures in mig.h. This is only used
- * here and is separated from the structures because users need not be
- * aware of conversion issues.
- * *
- ********************************************************************
- * IMPORTANT NOTE *
- ********************************************************************
- * *
- * Changes to the structures in mig.h must also be reflected below. *
- * *
- ********************************************************************
- */
-
- /*
- * The Mig_LoadVector is imbedded in a Mig_Info. With old compilers
- * we can't concatenate anyway.
- */
- #define MIGD_LOADVEC_FMT "{w8d3}"
- #define MIGD_INFO_FMT "{w12{w8d3}}"
- #define MIGD_UP_IN_FMT MIGD_INFO_FMT
-
- #define MIGD_GETINFO_IN_FMT "{w2}"
- #ifdef __STDC__
- #define MIGD_GETINFO_OUT_FMT "w2" MIGD_INFO_FMT "*"
- #else /* __STDC__ */
- #define MIGD_GETINFO_OUT_FMT "w2{w12{w8d3}}*"
- #endif /* __STDC__ */
-
-
- #define MIGD_GETIDLE_IN_FMT "{w4}"
- #define MIGD_GETIDLE_OUT_FMT "w*"
-
-
-
- #define MIGD_DONE_IN_FMT "w*"
- #define MIGD_REMOVE_IN_FMT MIGD_DONE_IN_FMT
-
- #define MIGD_CHANGE_IN_FMT "w"
- #define MIGD_PARAMS_FMT "{w4d2}"
- #define MIGD_STATS_FMT "{w12{b12w45{w20}2}8}"
- #define MIGD_GET_UPDATE_OUT_FMT "w"
- #define MIGD_EVICT_OUT_FMT "w"
-
- /*
- * When a daemon starts up, it does an ioctl with a full Mig_Info to
- * start things off. Then it does writes with new load vectors, and
- * ioctls to flag special cases such as eviction.
- */
- #define MIGD_DAEMON_IN_FMT MIGD_INFO_FMT
-
- static IoctlCallback ioctlCallbacks[] = {
- { Global_GetLoadInfo, MIGD_GETINFO_IN_FMT, MIGD_GETINFO_OUT_FMT},
- { Global_GetIdle, MIGD_GETIDLE_IN_FMT, MIGD_GETIDLE_OUT_FMT},
- { Global_DoneIoctl, MIGD_DONE_IN_FMT, (char *) NULL},
- { Global_RemoveHost, MIGD_REMOVE_IN_FMT, (char *) NULL},
- { Global_HostUp, MIGD_UP_IN_FMT, (char *) NULL},
- { Global_ChangeState, MIGD_CHANGE_IN_FMT, (char *) NULL},
- { Migd_GetParms, (char *) NULL, MIGD_PARAMS_FMT},
- { Migd_SetParms, MIGD_PARAMS_FMT, (char *) NULL},
- { Global_GetStats, (char *) NULL, MIGD_STATS_FMT},
- { Global_GetUpdate, (char *) NULL, MIGD_GET_UPDATE_OUT_FMT},
- { Migd_EvictIoctl, (char *) NULL, MIGD_EVICT_OUT_FMT},
- { Global_ResetStats, (char *) NULL, (char *) NULL},
- };
-
- /*
- * Pdev identifier for the master end of the pdev, when open.
- */
- static Pdev_Token pdev = (Pdev_Token) NULL;
-
- static char *pdevName; /* File name of the pdev. */
-
- static int nextOpenID = 0; /* Identifier for next pdev
- open by a client. */
-
-
-
- List_Links openStreamListHdr; /* List of open pdevs. */
- List_Links *openStreamList; /* Pointer to list, used in calls. */
-
- int migPdev_Debug = 0;
-
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * MigPdev_Init --
- *
- * Initialize data structures for this module.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Open stream list is set up.
- *
- *----------------------------------------------------------------------
- */
-
- void
- MigPdev_Init()
- {
-
- openStreamList = &openStreamListHdr;
- List_Init(openStreamList);
- if (migPdev_Debug > 5) {
- pdev_Trace = 1;
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * MigPdev_OpenMaster --
- *
- * Set up the master end of a pseudo-device. This can be either
- * the host-specific pdev or the global pdev, as specified by the
- * global variable migd_GlobalMaster.
- *
- * Results:
- * 0 for successful completion, -1 for error.
- *
- * Side effects:
- * Opens pseudo-device as master.
- *
- *----------------------------------------------------------------------
- */
-
- int
- MigPdev_OpenMaster()
- {
- struct stat atts;
-
- if (migPdev_Debug > 1) {
- PRINT_PID;
- fprintf(stderr, "MigPdev_OpenMaster -\n");
- }
-
- if (migd_GlobalMaster) {
- pdevName = migd_GlobalPdevName;
- } else {
- pdevName = migd_LocalPdevName;
- }
-
- /*
- * Open pdev. If it's the global pdev and we can't open it, then
- * presumably someone else beat us to it. That's fine, let
- * him handle it. In any case, punt the error to our caller.
- */
- if (migPdev_Debug > 2) {
- PRINT_PID;
- fprintf(stderr, "MigPdev_OpenMaster - Open %s\n", pdevName);
- }
- #ifdef notdef
- pdev_Trace = 0;
- #endif
- /*
- * If we're opening the local pdev, and we've gotten this far, we
- * know the global master recognizes us as the only daemon on this
- * host. Therefore, ensure against leftover masters by removing the
- * pdev in case it already exists. Note that statting the file
- * may result in an error even though it actually exists, due to
- * trying to get attributes associated with a nonexistent pdev master.
- */
- if (!migd_GlobalMaster) {
- if (migPdev_Debug > 0 && stat(pdevName, &atts) == 0) {
- fprintf(stderr, "Warning: removing leftover pdev %s.\n",
- pdevName);
- }
- (void) unlink(pdevName);
- }
- pdev = Pdev_Open(pdevName, NULL, 0, 0, &service, NULL);
- if (pdev == NULL) {
- if (migPdev_Debug > 0) {
- PRINT_PID;
- fprintf(stderr, "MigPdev_OpenMaster: %s\n", pdev_ErrorMsg);
- }
- errno = ENODEV;
- return (-1);
- }
-
- if (migPdev_Debug > 1) {
- PRINT_PID;
- fprintf(stderr, "MigPdev_OpenMaster - completed successfully\n");
- }
-
- return (0);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * MigPdev_End --
- *
- * Terminate service of the master end of the pdev.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The pdev is removed and closed.
- *
- *----------------------------------------------------------------------
- */
-
- void
- MigPdev_End()
- {
- int status;
-
- if (migPdev_Debug > 2) {
- PRINT_PID;
- fprintf(stderr, "MigPdev_End -\n");
- }
-
- Pdev_Close(pdev);
- pdev = NULL;
-
- status = unlink(pdevName);
- if (status == -1) {
- SYSLOG2(LOG_WARNING, "couldn't remove %s: %s\n",
- pdevName, strerror(errno));
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * MigPdev_Stat --
- *
- * Perform an fstat on the descriptor associated with the pdev we
- * are controlling. .... OBSOLETE (never used)
- *
- * Results:
- * On error, -1 is returned and errno is set to the error returned
- * by fstat; else 0 is returned.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- #ifdef 0
- int
- MigPdev_Stat(attsPtr)
- struct stat *attsPtr;
- {
- int stream = Pdev_GetStreamID(pdev);
-
- if (migPdev_Debug > 2) {
- PRINT_PID;
- fprintf(stderr, "MigPdev_Stat -\n");
- }
- return(fstat(stream, attsPtr));
- }
- #endif
-
-
- /*
- *----------------------------------------------------------------------
- *
- * SendSignal --
- *
- * Send a signal over a stream. Only used for signalling other
- * daemons upon normal master termination (for debugging).
- *
- * Results:
- * 0 is returned, since we don't want to stop partway through.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-
- static int
- SendSignal(streamPtr, clientData)
- Pdev_Stream *streamPtr; /* Pdev stream, containing streamID */
- ClientData clientData; /* Signal to send, as a ClientData */
- {
- #ifdef USE_PDEV_SIGNALS
- Pdev_Signal sig;
- #endif /* USE_PDEV_SIGNALS */
- int status;
- Migd_OpenStreamInfo *cltPtr =
- (Migd_OpenStreamInfo *) streamPtr->clientData;
-
- if (cltPtr->type != MIGD_DAEMON) {
- return(0);
- }
- if (migPdev_Debug > 3) {
- PRINT_PID;
- fprintf(stderr, "SendSignal - sending signal to process %x\n",
- cltPtr->processID);
- }
-
- #ifdef USE_PDEV_SIGNALS
- sig.signal = (unsigned int) clientData;
- sig.code = 0;
- status = Fs_IOControl(streamPtr->streamID, IOC_PDEV_SIGNAL_OWNER,
- sizeof(Pdev_Signal), (char *) &sig, 0, (char *) NULL);
- #else /* USE_PDEV_SIGNALS */
- status = Sig_Send((unsigned int) clientData, cltPtr->processID, 0);
- #endif /* USE_PDEV_SIGNALS */
- if (status != SUCCESS && migPdev_Debug > 0) {
- PRINT_PID;
- fprintf(stderr, "SendSignal: error sending signal to process %x: %s\n",
- cltPtr->processID, Stat_GetMsg(status));
- }
- return(0);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * MigPdev_SignalClients --
- *
- * Send a signal to all clients.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- void
- MigPdev_SignalClients(sig)
- int sig; /* Signal to send. */
- {
- if (migPdev_Debug > 2) {
- PRINT_PID;
- fprintf(stderr, "MigPdev_SignalClients -\n");
- }
-
- (void) Pdev_EnumStreams(pdev, SendSignal, (ClientData) sig);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * MigPdev_MakeReady --
- *
- * Make a pdev stream readable, so someone selecting on it
- * will know to do an ioctl. The ClientData is either NULL or
- * a function to determine whether to make this stream selectable.
- *
- * Results:
- * If an error occurs during the ioctl, then that error is returned,
- * else 0.
- *
- * Side effects:
- * The stream is marked.
- *
- *----------------------------------------------------------------------
- */
-
-
- int
- MigPdev_MakeReady(streamPtr, clientData)
- Pdev_Stream *streamPtr; /* Pdev stream, containing streamID */
- ClientData clientData; /* A function for selection, or NULL. */
- {
- int (*func)();
- int status;
- Migd_OpenStreamInfo *cltPtr = (Migd_OpenStreamInfo *) streamPtr->clientData;
-
- func = (int (*) ()) clientData;
- if (func != (int (*) ()) NULL) {
- if (!(*func)(cltPtr)) {
- return(0);
- }
- }
- cltPtr->defaultSelBits |= FS_READ;
- status = Fs_IOControl(streamPtr->streamID, IOC_PDEV_READY, sizeof(int),
- (char *) &cltPtr->defaultSelBits, 0, (char *) NULL);
- /*
- * Note any errors, but only return non-zero status if we had
- * no selection function (hence were notifying a particular
- * client rather than a bunch at once).
- */
- if (status != 0) {
- if (migPdev_Debug > 0) {
- PRINT_PID;
- fprintf(stderr, "Error making stream selectable for client %x: %s\n",
- cltPtr->processID, Stat_GetMsg(status));
- }
- if (func != (int (*) ()) NULL) {
- return(0);
- }
- return(status);
- }
- return(0);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * DaemonSelectPredicate --
- *
- * Selection predicate to just get clients that are daemons.
- *
- * Results:
- * 1 if a daemon, 0 otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static int
- DaemonSelectPredicate(cltPtr)
- Migd_OpenStreamInfo *cltPtr;
- {
- if (cltPtr->type == MIGD_DAEMON) {
- return(Global_IsHostUp(cltPtr->host));
- } else {
- return(0);
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * MigPdev_NotifyDaemons --
- *
- * Make migration daemons exceptable. (To notify a particular
- * client, use MigPdev_MakeReady directly).
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- void
- MigPdev_NotifyDaemons()
- {
-
- if (migPdev_Debug > 2) {
- PRINT_PID;
- fprintf(stderr, "MigPdev_NotifyDaemons -\n");
- }
-
- (void) Pdev_EnumStreams(pdev, MigPdev_MakeReady,
- (ClientData) DaemonSelectPredicate);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * PdevOpen --
- *
- * Service an open request for the pdev.
- *
- * Results:
- * 0, or an error condition.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- /* ARGSUSED */
- static int
- PdevOpen(data, streamPtr, buff, flags, processID, host, user, selPtr)
- ClientData data; /* Ignored. */
- Pdev_Stream *streamPtr; /* Information for the stream. */
- char *buff; /* Ignored */
- int flags; /* Flags passed to Fs_Open. */
- int processID; /* Id of process doing open. */
- int host; /* Host on which opened. */
- int user; /* Userid of opener. */
- int *selPtr; /* Bits for Fs_Select. */
- {
- Migd_OpenStreamInfo *cltPtr;
-
- if (migPdev_Debug > 2) {
- PRINT_PID;
- fprintf(stderr, "PdevOpen - request from %d:%x\n", host, processID);
- }
-
- if (migd_Quit) {
- if (migPdev_Debug > 0) {
- PRINT_PID;
- fprintf(stderr,
- "PdevOpen - can't handle request from %d:%x because we are shutting down.\n",
- host, processID);
- }
- return(ESHUTDOWN);
- }
-
- /* Check valid open flags */
- flags &= FS_USER_FLAGS;
- if (flags & ~(FS_WRITE | FS_READ)) {
- if (migPdev_Debug > 0) {
- PRINT_PID;
- fprintf(stderr, "PdevOpen - bad flags %x\n", flags);
- }
- return(EACCES);
- }
-
- cltPtr = mnew(Migd_OpenStreamInfo);
- bzero((char *) cltPtr, sizeof(Migd_OpenStreamInfo));
- cltPtr->streamPtr = streamPtr;
- cltPtr->user = user;
- cltPtr->host = host;
- cltPtr->processID = processID;
- cltPtr->openID = nextOpenID;
- /*
- * By default, processes can't read or write the pdev, they must
- * use ioctls. They can use an ioctl to register a long-term
- * interest, such as if they're a loadavg daemon or a load widget,
- * but until then the default is not to be able to select on this
- * stream. (In addition, they can select on the stream and be
- * told it's readable if there's a change in status, but again,
- * it's unreadable by default until that happens.) This default
- * value is used to make it easy for routines to reset the select
- * bits as appropriate.
- */
- if (migd_GlobalMaster) {
- cltPtr->defaultSelBits = 0;
- cltPtr->type = ((user == 0) && (flags & FS_WRITE)) ?
- MIGD_DAEMON : MIGD_USER;
- } else {
- cltPtr->defaultSelBits = FS_READ;
- cltPtr->type = MIGD_LOCAL;
- }
- nextOpenID++;
- streamPtr->clientData = (ClientData) cltPtr;
- List_Init(&cltPtr->currentRequests);
- List_Init(&cltPtr->messages);
- List_InitElement(&cltPtr->nextStream);
- List_Insert((List_Links *)cltPtr, LIST_ATREAR(openStreamList));
- cltPtr->waitPtr = (Migd_WaitList *) NULL;
-
- *selPtr = cltPtr->defaultSelBits;
-
- if (migPdev_Debug > 3) {
- PRINT_PID;
- fprintf(stderr, "PdevOpen - returning status 0\n");
- }
-
- return(0);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * PdevClose --
- *
- * Service a close request for the pdev. Clean up state, either
- * marking a host as down if the daemon on that host closed its
- * connection, or freeing hosts used by a client if it closes the
- * connection without freeing them first.
- *
- * Results:
- * 0, or an error condition.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static int
- PdevClose(streamPtr)
- Pdev_Stream *streamPtr; /* Information for the stream */
- {
- Migd_OpenStreamInfo *cltPtr;
-
-
- cltPtr = (Migd_OpenStreamInfo *) streamPtr->clientData;
- if (cltPtr == (Migd_OpenStreamInfo *) NULL) {
- /*
- * Stream wasn't fully opened -- if, for example, we were quitting
- * at the time.
- */
- return(0);
- }
-
- if (migPdev_Debug > 3) {
- PRINT_PID;
- fprintf(stderr, "PdevClose - pid %x\n", cltPtr->processID);
- }
-
- switch (cltPtr->type) {
- case MIGD_DAEMON: {
- if (migPdev_Debug > 1) {
- PRINT_PID;
- fprintf(stderr, "PdevClose - daemon %x on host %d exited\n",
- cltPtr->processID, cltPtr->host);
- }
- (void) Global_HostDown(cltPtr->host, 1);
- break;
- }
- case MIGD_USER: {
- if (migPdev_Debug > 2) {
- PRINT_PID;
- fprintf(stderr, "PdevClose - process closed pdev\n");
- }
- if (migd_GlobalMaster) {
- /*
- * Clean up after the process, by releasing hosts and
- * recording statistics.
- */
- (void) Global_Done(cltPtr, MIG_ALL_HOSTS, 1);
- }
- break;
- }
- case MIGD_CLOSED:
- case MIGD_NEW: {
- if (migPdev_Debug > 0) {
- PRINT_PID;
- fprintf(stderr,
- "PdevClose - never heard from process %x, or connection is unusable.\n",
- cltPtr->processID);
- }
- break;
- }
- case MIGD_LOCAL: {
- if (migPdev_Debug > 2) {
- PRINT_PID;
- fprintf(stderr,
- "PdevClose - local process %x exited.\n",
- cltPtr->processID);
- }
- break;
- default: {
- PRINT_PID;
- fprintf(stderr,
- "PdevClose - bad type (%d) for client type.\n",
- (int) cltPtr->type);
- }
- break;
- }
- }
-
- List_Remove((List_Links *)cltPtr);
- free((Address) cltPtr);
- return (0);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * PdevRead --
- *
- * Service a read request for the pdev. This is permitted when a
- * process wants the load vector for its own host, and talks to
- * its daemon directly. The master daemon doesn't service read
- * requests; requests for load go through the ioctl interface, which
- * also deals with byte swapping. Note: we don't check the hostID
- * of the requester, since after all the hostID could be a physical
- * host that's different from us but the same byte order, but
- * if someone on a different architecture tries to read our structure
- * they may get garbage.
- *
- * Results:
- * 0 for success, EINVAL is returned if we're not the local daemon
- * or the read isn't at least the size of a Mig_Info structure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- /* ARGSUSED */
- static int
- PdevRead(streamPtr, readPtr, freeItPtr, selectBitsPtr, sigPtr)
- Pdev_Stream *streamPtr; /* Service stream the client specified in its
- * kernel call. */
- Pdev_RWParam *readPtr; /* Read parameter block. Indicates size,
- * buffer, plus various IDs */
- Boolean *freeItPtr; /* Not used here. */
- int *selectBitsPtr; /* Store new select state of stream here. */
- Pdev_Signal *sigPtr; /* Signal information for returning signal. */
- {
- Migd_OpenStreamInfo *cltPtr;
-
- cltPtr = (Migd_OpenStreamInfo *) streamPtr->clientData;
- *selectBitsPtr = cltPtr->defaultSelBits;
-
- if (migPdev_Debug > 3) {
- PRINT_PID;
- fprintf(stderr, "PdevRead - request from %d:%x\n",
- cltPtr->host, cltPtr->processID);
- }
- if (migd_Quit) {
- sigPtr->signal = SIG_TERM;
- }
- if (migd_GlobalMaster) {
- /*
- * Wrong interface to communicate with the global master.
- */
- return (EINVAL);
- }
- if (readPtr->length < sizeof(Mig_Info)) {
- if (migPdev_Debug > 0) {
- PRINT_PID;
- fprintf(stderr, "PdevRead - short read from %d:%x\n",
- cltPtr->host, cltPtr->processID);
- }
- return(EINVAL);
- }
-
- Migd_GetLocalLoad(readPtr->buffer);
- readPtr->length = sizeof(Mig_Info);
- return (0);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * PdevWrite --
- *
- * Service a write request for the pdev. Write requests can be from
- * daemons, telling us a new load vector, or from clients, requesting
- * or returning one or more hosts.
- *
- * Results:
- * An error status, or 0 for success, is returned.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- /* ARGSUSED */
- static int
- PdevWrite(streamPtr, async, writePtr, selectBitsPtr, sigPtr)
- Pdev_Stream *streamPtr; /* Service stream the client specified in its
- * kernel call. */
- int async; /* Non-zero means this is an asynchronous
- * write request. */
- Pdev_RWParam *writePtr; /* Write parameter block. Indicates size,
- * offset, and buffer, among other things */
- int *selectBitsPtr; /* Just set to default. */
- Pdev_Signal *sigPtr; /* Signal to return, if any */
- {
- Migd_OpenStreamInfo *cltPtr;
- Mig_LoadVector loadVec;
- Mig_LoadVector *loadPtr;
- int status;
- int inBufSize;
- int outBufSize;
-
- cltPtr = (Migd_OpenStreamInfo *) streamPtr->clientData;
-
- if (migPdev_Debug > 3) {
- PRINT_PID;
- fprintf(stderr, "PdevWrite - packet from %d:%x\n", cltPtr->host,
- cltPtr->processID);
- }
-
- if (migd_Quit) {
- sigPtr->signal = SIG_TERM;
- }
-
- *selectBitsPtr = cltPtr->defaultSelBits;
-
- /*
- * Process packet.
- */
- if (cltPtr->type != MIGD_DAEMON) {
- if (migPdev_Debug > 1) {
- PRINT_PID;
- fprintf(stderr, "PdevWrite - got invalid write from %d:%x\n",
- cltPtr->host, cltPtr->processID);
- }
- return(EPERM);
- }
- if (writePtr->length < sizeof(Mig_LoadVector)) {
- if (migPdev_Debug > 0) {
- SYSLOG3(LOG_WARNING,
- "PdevWrite - short write from process %x: %d bytes of %d\n",
- cltPtr->processID, writePtr->length,
- sizeof(Mig_LoadVector));
- }
- return(EINVAL);
- }
- if (cltPtr->format != FMT_MY_FORMAT) {
- inBufSize = writePtr->length;
- outBufSize = sizeof(Mig_LoadVector);
- status = Fmt_Convert(MIGD_LOADVEC_FMT,
- cltPtr->format,
- &inBufSize,
- writePtr->buffer,
- FMT_MY_FORMAT,
- &outBufSize,
- (char *) &loadVec);
- if (status != FMT_OK || inBufSize != writePtr->length ||
- outBufSize != sizeof(Mig_LoadVector)) {
- PRINT_PID;
- fprintf(stderr,
- "PdevWrite - error swapping Mig_LoadVector structure, status = %d, swapped %d->%d of %d.\n",
- status, inBufSize, outBufSize, sizeof(Mig_LoadVector));
- return(EINVAL);
- }
- loadPtr = &loadVec;
- } else {
- loadPtr = (Mig_LoadVector *) writePtr->buffer;
- }
- status = Global_UpdateLoad(cltPtr, loadPtr);
- if (status == 0 && !async) {
- writePtr->length = sizeof(Mig_LoadVector);
- }
-
- return(status);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * PdevIoctl --
- *
- * Basic entry point for communications with a server. This
- * routine handles byte-swapping, but the real work is done
- * elsewhere.
- *
- * Results:
- * An error status, or 0 for success, is returned.
- *
- * Side effects:
- * Variable.
- *
- *----------------------------------------------------------------------
- */
-
- /* ARGSUSED */
- static int
- PdevIoctl(streamPtr, ioctlPtr, selectBitsPtr, sigPtr)
- Pdev_Stream *streamPtr; /* Service stream the client specified in its
- * kernel call. */
- Pdev_IOCParam *ioctlPtr; /* I/O control parameters */
- int *selectBitsPtr; /* Store new select state here. */
- Pdev_Signal *sigPtr; /* Returned signal, if any */
- {
- Migd_OpenStreamInfo *cltPtr;
- int status;
- Address inBuffer;
- Address outBuffer;
- int bufSize; /* Temporary holder for buffer size passed
- to Fmt_Convert. */
- int inBufSize; /* Size of the real input buffer. */
- int outBufSize; /* Size of the real output buffer. */
- int command;
- char *swapBuffer = NULL;
- IoctlCallback *callbackPtr;
-
- cltPtr = (Migd_OpenStreamInfo *) streamPtr->clientData;
- command = ioctlPtr->command;
-
- if (migPdev_Debug > 3) {
- PRINT_PID;
- fprintf(stderr, "PdevIoctl - command %d from %x\n", command,
- cltPtr->processID);
- }
-
- /*
- * Set the selectBits ptr up front in case we return an error early on.
- */
- *selectBitsPtr = cltPtr->defaultSelBits;
- if (migd_Quit) {
- sigPtr->signal = SIG_TERM;
- }
-
- outBufSize = ioctlPtr->outBufSize;
- inBufSize = ioctlPtr->inBufSize;
-
- if (command == IOC_SET_OWNER) {
- return(0);
- }
-
- if (command <= IOC_GENERIC_LIMIT ||
- command > IOC_MIG_LASTCMD) {
- if (migPdev_Debug > 2) {
- SYSLOG2(LOG_WARNING, "undefined ioctl from %x: %d\n",
- cltPtr->processID, command);
- }
- return(EINVAL);
- }
-
-
-
- callbackPtr = &ioctlCallbacks[command - IOC_GENERIC_LIMIT - 1];
-
- /*
- * We need to swap if we're different byte orders. We swap right now if
- * this ioctl takes input (inFmt is non-null). We allocate extra
- * space for swapping later if outFmt is non-null. We save the format away
- * for use in read/write calls.
- */
- cltPtr->format = ioctlPtr->format;
- if (ioctlPtr->format != FMT_MY_FORMAT) {
- if (callbackPtr->inFmt != (char *) NULL) {
- bufSize = inBufSize;
- swapBuffer = Malloc(inBufSize);
- status = Fmt_Convert(callbackPtr->inFmt,
- ioctlPtr->format,
- &inBufSize,
- ioctlPtr->inBuffer,
- FMT_MY_FORMAT,
- &bufSize,
- swapBuffer);
- if (status != FMT_OK || inBufSize != ioctlPtr->inBufSize) {
- SYSLOG3(LOG_ERR,
- "PdevIoctl - error swapping ioctl input buffer, status = %d, swapped %d of %d.\n",
- status, inBufSize, ioctlPtr->inBufSize);
- free(swapBuffer);
- return(EINVAL);
- }
- inBuffer = swapBuffer;
- inBufSize = bufSize;
- } else {
- inBuffer = ioctlPtr->inBuffer;
- }
- if (callbackPtr->outFmt != (char *) NULL) {
- outBuffer = Malloc(outBufSize);
- } else {
- outBuffer = ioctlPtr->outBuffer;
- }
- } else {
- inBuffer = ioctlPtr->inBuffer;
- outBuffer = ioctlPtr->outBuffer;
- }
-
-
- status = (*callbackPtr->routine)
- (cltPtr, ioctlPtr->command, inBuffer, inBufSize, outBuffer,
- &outBufSize);
-
- #ifdef lint
- status = Global_GetLoadInfo(cltPtr, ioctlPtr->command, inBuffer,
- inBufSize, outBuffer, &outBufSize);
- status = Global_GetIdle(cltPtr, ioctlPtr->command, inBuffer, inBufSize,
- outBuffer, &outBufSize);
- status = Global_DoneIoctl(cltPtr, ioctlPtr->command, inBuffer, inBufSize,
- outBuffer, &outBufSize);
- status = Global_RemoveHost(cltPtr, ioctlPtr->command, inBuffer, inBufSize,
- outBuffer, &outBufSize);
- status = Global_HostUp(cltPtr, ioctlPtr->command, inBuffer, inBufSize,
- outBuffer, &outBufSize);
- status = Global_ChangeState(cltPtr, ioctlPtr->command, inBuffer, inBufSize,
- outBuffer, &outBufSize);
- status = Global_GetStats(cltPtr, ioctlPtr->command, inBuffer, inBufSize,
- outBuffer, &outBufSize);
- #endif /* lint */
-
- if (status == 0) {
- /*
- * This time we need to swap if we're different byte orders and if
- * this ioctl returns output (outFmt is non-null).
- */
- if (ioctlPtr->format != FMT_MY_FORMAT &&
- callbackPtr->outFmt != (char *) NULL) {
- int origSize;
-
- bufSize = outBufSize;
- origSize = outBufSize;
- status = Fmt_Convert(callbackPtr->outFmt,
- FMT_MY_FORMAT,
- &bufSize,
- outBuffer,
- ioctlPtr->format,
- &outBufSize,
- ioctlPtr->outBuffer);
- if (status != FMT_OK || bufSize != origSize) {
- SYSLOG3(LOG_ERR,
- "PdevIoctl - error swapping ioctl output buffer, status = %d, swapped %d of %d.\n",
- status, bufSize, origSize);
- status = EINVAL;
- }
- }
- }
- /*
- * Free up extra buffers.
- */
- if (inBuffer != ioctlPtr->inBuffer) {
- free(inBuffer);
- }
- if (outBuffer != ioctlPtr->outBuffer) {
- free(outBuffer);
- }
-
- /*
- * Reset the selectBits ptr based on current value.
- */
- *selectBitsPtr = cltPtr->defaultSelBits;
-
- /*
- * Return a unix status since that's what pdev expects. It will
- * convert to a sprite value if needed.
- */
- return (status);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * MigPdev_CloseAllStreams --
- *
- * Close all open client streams, and the stream for any existing
- * pdev master. This occurs when we fork a process
- * to become the new global master: the child closes its streams.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Memory for the client records is freed.
- *
- *----------------------------------------------------------------------
- */
-
- void
- MigPdev_CloseAllStreams()
- {
- #ifdef notdef
- List_Links *listPtr;
- Migd_OpenStreamInfo *cltPtr;
-
- while (!List_IsEmpty(openStreamList)) {
- listPtr = List_First(openStreamList);
- List_Remove(listPtr);
- cltPtr = (Migd_OpenStreamInfo *) listPtr;
- close(cltPtr->streamPtr->streamID);
- free(cltPtr);
- }
- #endif
- if (pdev != (Pdev_Token) NULL) {
- Pdev_Close(pdev);
- }
- }
- @
-
-
- 2.0
- log
- @Changing version numbers.
- @
- text
- @d28 1
- a28 1
- static char rcsid[] = "$Header: /sprite/src/daemons/migd/RCS/migPdev.c,v 1.9 90/05/28 17:07:27 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
- d159 14
- a172 6
- *----------------------------------------------------------------------
- * * MigPdev_Init -- * * Initialize data structures for this module. *
- * Results: * None. * * Side effects: * Open stream list is
- set up. *
- *----------------------------------------------------------------------
- */
- d180 3
- d621 1
- a621 1
- List_InitElement((List_Links *) cltPtr);
- d1113 1
- d1116 1
- a1116 2
-
- #ifdef notdef
- @
-
-
- 1.9
- log
- @changed to use FMT_MY_FORMAT now that it exists.
- @
- text
- @d28 1
- a28 1
- static char rcsid[] = "$Header: /sprite/src/daemons/migd/RCS/migPdev.c,v 1.8 90/05/02 12:31:27 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
- @
-
-
- 1.8
- log
- @added comments
- @
- text
- @d28 1
- a28 1
- static char rcsid[] = "$Header: /sprite/src/daemons/migd/RCS/migPdev.c,v 1.7 90/04/27 00:59:18 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
- d112 1
- a112 1
- #define MIGD_STATS_FMT "{w8{b12w49{w20}2}8}"
- a137 2
- int myFormat = -1; /* my byte order format, see fmt.h */
-
- d172 1
- a172 15
-
-
- /*
- * XXX hack city!
- */
- #ifdef ds3100
- myFormat = FMT_MIPS_FORMAT;
- #else
- #ifdef sun4
- myFormat = FMT_SPARC_FORMAT;
- #else
- myFormat = FMT_68K_FORMAT;
- #endif
- #endif
- }
- d847 1
- a847 1
- if (migPdev_Debug > 0) {
- d863 1
- a863 1
- if (cltPtr->format != myFormat) {
- d870 1
- a870 1
- myFormat,
- d959 4
- a962 2
- SYSLOG2(LOG_WARNING, "undefined ioctl from %x: %d\n",
- cltPtr->processID, command);
- d977 1
- a977 1
- if (ioctlPtr->format != myFormat) {
- d985 1
- a985 1
- myFormat,
- d992 1
- d1037 1
- a1037 1
- if (ioctlPtr->format != myFormat &&
- d1044 1
- a1044 1
- myFormat,
- @
-
-
- 1.7
- log
- @changes for statistics gathering.
- @
- text
- @d28 1
- a28 1
- static char rcsid[] = "$Header: /sprite/src/daemons/migd/RCS/migPdev.c,v 1.6 90/04/24 18:00:41 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
- d697 5
- a701 1
- (void) Global_Done(cltPtr, MIG_ALL_HOSTS);
- d1041 2
- d1086 4
- @
-
-
- 1.6
- log
- @intermediate checkpoint
- @
- text
- @d28 1
- a28 1
- static char rcsid[] = "$Header: /sprite/src/daemons/migd/RCS/migPdev.c,v 1.5 90/04/03 11:09:35 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
- d112 1
- a112 1
- #define MIGD_STATS_FMT "{w4}"
- d161 6
- a166 14
- *----------------------------------------------------------------------
- *
- * MigPdev_Init --
- *
- * Initialize data structures for this module.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Open stream list is set up.
- *
- *----------------------------------------------------------------------
- */
- d314 1
- a314 1
- * are controlling.
- d326 1
- d329 1
- a329 1
- struct stats *attsPtr;
- d339 1
- a451 1
- int val;
- d597 1
- a602 4
- cltPtr->numRequested = 0;
- cltPtr->numAssigned = 0;
- cltPtr->numInUse = 0;
- cltPtr->maxRequested = 0;
- d666 1
- d668 7
- @
-
-
- 1.5
- log
- @changed a syslog warning to an error file warning only.
- @
- text
- @d28 1
- a28 1
- static char rcsid[] = "$Header: /sprite/src/daemons/migd/RCS/migPdev.c,v 1.4 90/03/14 12:49:57 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
- d135 1
- d609 4
- @
-
-
- 1.4
- log
- @debugging info
- @
- text
- @d28 1
- a28 1
- static char rcsid[] = "$Header: /sprite/src/daemons/migd/RCS/migPdev.c,v 1.3 90/03/12 13:45:47 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
- d254 1
- a254 1
- SYSLOG1(LOG_INFO, "Warning: removing leftover pdev %s.\n",
- @
-
-
- 1.3
- log
- @print pid's before messages in global log file; print dates here and
- there; open files in append mode; changed file names to be in admin
- subdir. [this is a recording. beep!]
- @
- text
- @d28 1
- a28 1
- static char rcsid[] = "$Header: /sprite/src/daemons/migd/RCS/migPdev.c,v 1.2 90/02/28 10:50:24 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
- d478 2
- a479 2
- fprintf(stderr, "Error making stream selectable for client %x\n",
- cltPtr->processID);
- d682 2
- a683 2
- fprintf(stderr, "PdevClose - daemon on host %d exited\n",
- cltPtr->host);
- d952 1
- a952 1
- * Seet the selectBits ptr up front in case we return an error early on.
- d968 2
- a969 1
- SYSLOG1(LOG_WARNING, "undefined ioctl: %d\n", command);
- @
-
-
- 1.2
- log
- @print msgs to both syslog & error log when appropriate. remove the
- pdev before opening it if it's the local pdev since the global daemon
- has recognized process already.
- @
- text
- @d28 1
- a28 1
- static char rcsid[] = "$Header: /sprite/src/daemons/migd/RCS/migPdev.c,v 1.1 90/02/15 19:19:06 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
- d222 1
- d238 1
- d253 1
- a253 1
- if (migPdev_Debug > 0 && stat(pdevName, &atts)) {
- d262 1
- d270 1
- d300 1
- d340 1
- d381 1
- d395 1
- d424 1
- d477 1
- d539 1
- d578 1
- d584 1
- d596 1
- d638 1
- d674 1
- d681 1
- d690 1
- d701 1
- d710 1
- d717 4
- a720 3
- fprintf(stderr,
- "PdevClose - bad type (%d) for client type.\n",
- (int) cltPtr->type);
- d773 1
- d788 1
- d841 1
- d857 1
- d884 1
- d946 1
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @d28 1
- a28 1
- static char rcsid[] = "$Header: /user2/douglis/pdev_mig/migd/RCS/migPdev.c,v 2.4 90/02/14 11:46:35 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
- d42 1
- d44 1
- d219 2
- d242 15
- d304 32
- a335 2
- syslog(LOG_WARNING, "%s migd: couldn't remove %s: %s\n",
- migd_ProgName, pdevName, strerror(errno));
- d337 1
- d840 4
- a843 2
- fprintf(stderr, "PdevWrite - short write from %d:%x\n",
- cltPtr->host, cltPtr->processID);
- d870 1
- a870 1
- writePtr->length = outBufSize;
- d872 1
- d941 1
- a941 1
- syslog(LOG_WARNING, "%s: undefined ioctl: %d\n", migd_ProgName, command);
- d968 1
- a968 1
- syslog(LOG_ERR,
- d1027 1
- a1027 1
- syslog(LOG_ERR,
- d1077 1
- d1085 1
- @
-